<style scoped>
.chat_outer{height: 100%;position: relative;flex-direction: column;}
.chat_outer>.max{position: relative;overflow: hidden;}
.chat_outer>.max .to_bottom_button{position: absolute;bottom: 20px;right: 20px;transform: rotate(180deg);}
.message_list{overflow-y: auto;width: 100%;height: 100%;}
.message_list .time{text-align: center;font-size: 12px;color: var(--color-bg-re-r);padding-top: 12px;}
.message_row.reverse{flex-direction: row-reverse;}
.message_row{padding: 5px;align-items: flex-start;}
.message_row .img>img{width: 40px;height: 40px;overflow: hidden;border-radius: 4px;object-fit: contain;}
.message_row>.max{padding: 0 6px;flex-direction: column;align-items: flex-start;}
.message_row.reverse>.max{align-items: flex-end;}
.message_row>.max .nickname{font-size: 12px;}
.message_row>.max .content{font-size: 18px;border-radius: 6px;background: #fff;padding: 6px 8px;line-height: 1.2;width: auto;}
.message_row>.max .content.text{display: inline-block;}
.message_row.reverse>.max .content.text{background: var(--color-primary);}
.message_row .status{width: 40px;}

.input_box{width: 100%;background: #f9f9f9;align-items: flex-end;}
.input_box>*{padding: 10px 6px;}
.input_box .input{font-size: 18px;width: 100%;border-radius: 4px;background: #fff;padding: 4px;border: none;outline: none;}
.input_box div.input{min-height: 34px;max-height: 240px;height: auto;overflow-y: auto;}
.input_box div.input:empty::before{content: attr(placeholder);color: #999;}
.input_box .button{height: 34px;padding: 0 12px;background: var(--color-primary);color: #fff;display: flex;align-items: center;border-radius: 4px;}
</style>
<template>
  <div class="chat_outer flex">
    <div class="max">
      <van-pull-refresh v-model="loading" :disabled="finished" @refresh="refresh" pulling-text="下拉加载更多" loosing-text="释放加载更多" ref="message_list" class="message_list" @scroll="scroll">
        <template v-for="row in list">
          <p v-if="row.show_time" class="time">{{ row.create_time }}</p>
          <div class="message_row flex" :class="{reverse:row.user_id==me.id}">
            <div class="img"><img-referrer :src="row.user.head_img" alt=""/></div>
            <div class="max flex">
              <p v-if="1" class="nickname">{{ row.user.nickname }}</p>
              <div v-if="row.type=='img'" class="content img"><img-referrer :src="row.content" alt=""/></div>
              <div v-else class="content text">{{ row.content }}</div>
            </div>
            <div class="status"></div>
          </div>
        </template>
        <div ref="ref_to_bottom"></div>
      </van-pull-refresh>
      <van-button v-show="show_to_bottom" class="to_bottom_button" @click="to_bottom" type="primary" size="small" icon="back-top"/>
    </div>

    <div class="input_box flex">
      <div class="max">
        <div ref="input" class="input" contenteditable="true" placeholder=""></div>
      </div>
      <div><p class="button" @click="send_text">发送</p></div>
    </div>
  </div>
</template>

<script>


import s94Mjs from "s94-js";
import {ajax} from "@/js/api_tool.js";
import {_get, href_handle} from "@/vue_plugin/router_auto.js";
import {msg} from "@/js/vant_tool.js";
import ImgReferrer from "@/components/widget/ImgReferrer.vue";

export default {
  components: {ImgReferrer},
  data(){
    return {
      loading: false,
      finished: true,
      to_user_id: _get('to_user_id', 0),

      list: [],
      refresh_max_id: 0,
      loop_min_id: 0,
      loop_th: false,

      show_to_bottom: false,

      me: {id:1, nickname:'', head_img:''},
      you: {id:0, nickname:'', head_img:''},

    }
  },
  methods:{
    refresh(){
      let data = {to_user_id:this.to_user_id, n:20, 'order[id]':'desc'};
      if (this.refresh_max_id>0){
        data['where[id][lt]'] = this.refresh_max_id;
      }
      return new Promise((resolve)=>{
        ajax({url:'/home/log_message/list', data}, (res)=>{
          let list = res.data.list;
          this.loading = false;
          list.forEach(row=>{
            this.add_message(row, 0);
          })
          this.finished = list.length < data.n;
          if (list.length){
            this.refresh_max_id = list[list.length-1].id;
          }
          resolve(list);
          return false;
        },()=>{ this.loading = false; });
      })
    },
    loop_receive(){
      let data = {to_user_id:this.to_user_id, 'where[id][gt]':this.loop_min_id, 'order[id]':'asc'};
      if (!/\/message\/chat(\?|$)/.test(window.location.href)) return ; //如果路由不对，不再接受消息
      return new Promise((resolve)=>{
        ajax({url:'/home/log_message/list_receive', data}, (res)=>{
          let list = res.data.list;
          let dt_bottom_ratio = this.dt_bottom_ratio();
          list.forEach(row=>{
            let i = this.list.length-1;
            while (i>=0){
              let id = this.list[i].id;
              if (id < row.id) break; //遍历到id比当前消息id小为止，这样当前消息插入的位置就在此位置后面(i+1)
              i--;
            }
            this.add_message(row, i+1);
          })
          if (list.length){
            if (dt_bottom_ratio < 0.2) this.to_bottom();
            this.loop_min_id = list[list.length-1].id;
          }
          resolve(list);
          this.loop_th = setTimeout(()=>{ this.loop_receive() }, 3000); //每3秒获取一次接受的消息
          return false;
        });
      })
    },
    dt_bottom_ratio(){
      let dom = this.$refs.message_list.$el;
      if (!dom) return 0;
      let height = dom.offsetHeight;
      let dt_bottom = dom.scrollHeight - dom.scrollTop - height;
      return (dt_bottom/height);
    },
    scroll(){
      this.show_to_bottom = (this.dt_bottom_ratio() > 1);
    },
    to_bottom(){
      setTimeout(()=>{
        this.$refs.ref_to_bottom.scrollIntoView({block: "end", inline: "nearest"}, {behavior:'auto'});
      },20)
    },
    init(){
      ajax(`/home/log_message/init?to_user_id=${this.to_user_id}`, ({data})=>{
        this.me = data.me;
        this.you = data.you;
        this.refresh().then((list)=>{
          if (list.length) this.loop_min_id = list[0].id;
          this.loop_receive();
          this.to_bottom();
        });
      }, (res)=>{
        msg(`res.message`);
        return href_handle(-1, 1500);
      })
    },
    add_message(row, index){
      if (typeof index === 'undefined') index = this.list.length;
      row.user = row.user_id == this.me.id ? this.me : this.you;
      row.show_time = false;
      row.time_stamp = s94Mjs.strtodate(row.create_time, 'Y-M-D H:I:S').getTime();
      //和前一个消息比较判断当前消息是否显示时间
      let pre_row = this.list[index-1];
      if (pre_row){
        row.show_time = (Math.abs(row.time_stamp - pre_row.time_stamp) > 5*60*1000);
      }
      //和后一个消息比较，判断后一个消息是否显示时间
      let next_row = this.list[index]; //当前消息还没插入，所以后一个消息的序号为index
      if (next_row){
        next_row.show_time = (Math.abs(row.time_stamp - next_row.time_stamp) > 5*60*1000);
      }
      this.list.splice(index, 0, row);
    },
    send_text(){
      let text = this.$refs.input.innerText;
      if (!text) return;
      let data = {
        to_user_id: this.to_user_id,
        type: 'text',
        content: text,
      }
      let message_row = {
        user_id: this.me.id,
        status: 0,
        create_time: s94Mjs.date('Y-M-D H:I:S'),
      }
      ajax({url:'/home/log_message/add', data}, res=>{
        message_row = Object.assign(message_row, data);
        message_row.id = res.data;
        let dt_bottom_ratio = this.dt_bottom_ratio();
        this.add_message(message_row);
        if (dt_bottom_ratio < 0.2) this.to_bottom();
        this.$refs.input.innerText = '';
        return false;
      })
    },

  },
  computed:{},
  mounted(){
    this.init();
  },
  deactivated() {
    console.log('deactivated');
  },
  beforeRouteLeave(){
    console.log('beforeRouteLeave');
  },
}
</script>